<?php
/**
 * ObjFactory class
 * This class can be sub-classed for complete customization.
 * 
 * @author Jean-Lou Dupont
 * @version @@package-version@@
 */
//{{include
require_once 'web-bloks/ObjFactory/ObjFactory_Exception.php';
//include}}

class WB_ObjFactory
 {
 	/**
 	 * Singleton instance
 	 */
 	static $_instance = null;
	
 	/**
 	 * Constructor
 	 * Can't create multiple instances of this class.
 	 */
	protected function __construct( ) 
	{}
	/**
	 * Class Destructor
	 * Useful for debugging purposes.
	 * 
	 */
	public function __destruct()
	{
		self::$_instance = null;
	}	
	/**
	 * Sub-classes must provided their class name.
	 * Derived classes should sub-class this method according to:
	 * <code>
	 * 	public static function get( $class = __CLASS__ )
	 *  {
	 *		return parent::get( $class );
	 *	}	
	 * </code>
	 * 
	 * @return $obj
	 * @param $class Object[optional]
	 */	
	public static function get( $class = 'WB_ObjFactory' )
	{
		return self::getHandle( $class );
	}
		
	/**
	 * Returns the handle to the singleton instance.
	 * 
	 * @return $object singleton object
	 */	
	private static function getHandle( $class )
	{
		if ( !is_null( self::$_instance ) )
			return self::$_instance;
			
		self::$_instance = new $class();
		
		return self::$_instance;
	}

	/**
	 * Creates an instance object of the $class.
	 * This static method can be sub-classed.
	 * Creation exceptions can _not_ be caught.
	 * 
	 * @return $object Object
	 * @param $classe Object
	 * @param $params Object[optional]
	 */	
	public static function & factory( $classe, $params = null )
	{
		if ( self::isSingletonClass( $classe ))
			return self::handleSingleton( $classe, $params );
			
		return new $classe( $params );
	}
	/**
	 * Verifies if the required class must
	 * be handled through a singleton pattern.
	 * 
	 * @return boolean
	 * @param $classe string
	 */	
	protected static function isSingletonClass( $classe )
	{
		return method_exists( $classe, 'getSingleton' );
	}
	/**
	 * Handles creation / retrieval of a singleton of a $classe
	 * 
	 * @return object
	 * @param $classe string
	 * @param $params mixed
	 */	
	protected static function handleSingleton( $classe, $params )
	{
		$s = "return $classe::getSingleton( $params );";
		return eval( $s );
	}
	
 } // end class
